package com.zhuanzhuan.hero.user.facade;

import com.bj58.spat.scf.server.contract.annotation.ServiceBehavior;
import com.bj58.youpin.common.rpc.result.Result;
import com.bj58.zhuanzhuan.zzentry.common.service.entity.ServiceHeaderEntity;
import com.bj58.zhuanzhuan.zzentry.common.service.entity.ZZOpenScfBaseResult;
import com.bj58.zhuanzhuan.zzentry.common.service.model.openEntry.ZZHeader;
import com.bj58.zhuanzhuan.zzentry.common.service.model.openEntry.ZZMethod;
import com.bj58.zhuanzhuan.zzentry.common.service.model.openEntry.ZZParam;
import com.zhuanzhuan.hero.user.dto.reliable.QueryReliableListDTO;
import com.zhuanzhuan.hero.user.enums.ExceptionMsgEnum;
import com.zhuanzhuan.hero.user.enums.ReliableAuthTypeEnum;
import com.zhuanzhuan.hero.user.exception.BusinessException;
import com.zhuanzhuan.hero.user.helper.ZzLockHelper;
import com.zhuanzhuan.hero.user.service.IApolloService;
import com.zhuanzhuan.hero.user.service.IReliableService;
import com.zhuanzhuan.hero.user.util.Assert;
import com.zhuanzhuan.hero.user.util.ServiceHeaderUtil;
import com.zhuanzhuan.hero.user.vo.PageResultWrapper;
import com.zhuanzhuan.hero.user.vo.UserListItemVO;
import com.zhuanzhuan.hero.user.vo.label.CertificationQualifiedVO;
import com.zhuanzhuan.hero.user.vo.reliable.CertifyReliableDTO;
import com.zhuanzhuan.zzlock.lock.ZZEtcdLock;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import javax.annotation.Resource;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.Objects;

/**
 * @ClassName ReliableFacadeImpl
 * @Description
 * @Author hanjunjun
 * @Date 2024/7/5 14:34
 */
@ServiceBehavior
@Slf4j
public class ReliableFacadeImpl implements IReliableFacade {

    @Resource
    private IReliableService reliableService;

    @Resource
    private ZzLockHelper lockHelper;

    @Resource
    private IApolloService apolloService;

    @ZZMethod(value = "pageReliables", desc = "查询靠谱认证列表", publicAccess = false)
    @Override
    public ZZOpenScfBaseResult<PageResultWrapper<UserListItemVO>> pageReliables(@ZZHeader ServiceHeaderEntity header,
        @ZZParam("param") @Valid QueryReliableListDTO queryReliableListDTO) {
        Long fromUid = ServiceHeaderUtil.parseUid(header);
        Long toUid = Objects.nonNull(queryReliableListDTO.getToUid()) ?
            queryReliableListDTO.getToUid() : fromUid;
        return ZZOpenScfBaseResult.buildSucc(reliableService.pageReliables(fromUid, toUid, queryReliableListDTO));
    }

    @ZZMethod(value = "hasCertifyReliableQualify", desc = "是否有资格认证", publicAccess = false)
    @Override
    public ZZOpenScfBaseResult<CertificationQualifiedVO> hasCertifyReliableQualify(@ZZHeader ServiceHeaderEntity header,
        @ZZParam("param") CertifyReliableDTO certifyReliableDTO) {
        Long toUid = certifyReliableDTO.getToUid();
        Assert.notNull(toUid);
        CertificationQualifiedVO vo;
        boolean hasCertifyQualify = reliableService.hasCertifyQualify(ServiceHeaderUtil.parseUid(header), toUid);
        if (hasCertifyQualify) {
            vo = CertificationQualifiedVO.success();
        } else {
            vo = CertificationQualifiedVO.fail(apolloService.queryTips().getReliableAuthNoQualified());
        }

        return ZZOpenScfBaseResult.buildSucc(vo);
    }

    @ZZMethod(value = "certifyReliable", desc = "认证靠谱/不靠谱", publicAccess = false)
    @Override
    public ZZOpenScfBaseResult<Boolean> certifyReliable(@ZZHeader ServiceHeaderEntity header,
        @ZZParam("param") @Valid CertifyReliableDTO certifyReliableDTO) {
        if (ReliableAuthTypeEnum.UNRELIABLE.getCode().equals(certifyReliableDTO.getReliableType())) {
            //认证不靠谱时  原因和图片必传
            if (StringUtils.isBlank(certifyReliableDTO.getUnReliableReason()) ||
                CollectionUtils.isEmpty(certifyReliableDTO.getUnReliablePics())) {
                throw new BusinessException(ExceptionMsgEnum.PARAM_ERROR);
            }
        }

        Long fromUid = ServiceHeaderUtil.parseUid(header);
        Long toUid = certifyReliableDTO.getToUid();
        try (ZZEtcdLock lock = lockHelper.getLock(String.format("certifyReliable_%s_%s", fromUid, toUid))) {
            if (!lock.tryLock()) {
                log.info("获取锁失败");
                return ZZOpenScfBaseResult.buildErr(ExceptionMsgEnum.COMMON_ERROR.getCode(), ExceptionMsgEnum.COMMON_ERROR.getErrorMsg());
            }
            reliableService.certifyReliable(fromUid, certifyReliableDTO, header);
            return ZZOpenScfBaseResult.buildSucc(true);
        }
    }

    @ZZMethod(value = "cancelReliable", desc = "取消认证靠谱/不靠谱", publicAccess = false)
    @Override
    public ZZOpenScfBaseResult<Boolean> cancelReliable(@ZZHeader ServiceHeaderEntity header,
        @ZZParam("param") @Valid CertifyReliableDTO certifyReliableDTO) {
        Long fromUid = ServiceHeaderUtil.parseUid(header);
        Long toUid = certifyReliableDTO.getToUid();
        try (ZZEtcdLock lock = lockHelper.getLock(String.format("cancelReliable_%s_%s", fromUid, toUid))) {
            if (!lock.tryLock()) {
                log.info("获取锁失败");
                return ZZOpenScfBaseResult.buildErr(ExceptionMsgEnum.COMMON_ERROR.getCode(), ExceptionMsgEnum.COMMON_ERROR.getErrorMsg());
            }
            reliableService.cancelReliable(fromUid, certifyReliableDTO);
            return ZZOpenScfBaseResult.buildSucc(true);
        }
    }

    @Override
    public Result<PageResultWrapper<UserListItemVO>> queryReliableUsers(@NotNull Long uid, @NotNull Integer pageNum, @NotNull Integer pageSize) {
        QueryReliableListDTO dto = new QueryReliableListDTO();
        dto.setReliableType(ReliableAuthTypeEnum.RELIABLE.getCode());
        dto.setPageNum(pageNum);
        dto.setPageSize(pageSize);
        PageResultWrapper<UserListItemVO> wrapper = reliableService.pageReliables(uid, uid, dto);
        return Result.success(wrapper);
    }
}
